﻿/*
 * Twipler - Twitter Web Client with features.
 *  
 *  Copyright (C) 2009, 2010. Ian Quigley
 * 
 *  This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details. 
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see <http://www.gnu.org/licenses/>. 
 */

using System;
using System.Reflection;

namespace Twipler.Data.Entity
{
    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditReadonly : System.Attribute
    {}

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditIgnore: System.Attribute
    { }

    

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditSelectFrom: System.Attribute
    {
        public string MethodName;

        public EditSelectFrom(string methodName)
        {
            this.MethodName = methodName;
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditOrder: System.Attribute
    {
        public int Order;

        public EditOrder(int Order)
        {
            this.Order = Order;
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditCondition : System.Attribute
    {
        public enum Condition 
        {
            IsSuperAdmin,
            IsThemeModerator,
            SettingValueValidator
        };

        private Condition _condition;

        public bool IsRoleBasedReadonly
        {
            get
            {
                return (_condition == Condition.IsSuperAdmin) ||
                    (_condition == Condition.IsThemeModerator);
            }
        }

        public EditCondition(Condition condition)
        {
            _condition = condition;
        }
             
        public bool HasBeenMeet(Data.Entity.Base obj, System.Reflection.PropertyInfo pi)
        {
            switch (_condition)
            {
                case Condition.IsSuperAdmin:
                    return App.Current.Visitor.HasRole(Data.Entity.Twipler.VisitorRole.SuperAdmin);

                case Condition.IsThemeModerator:
                    return App.Current.Visitor.HasRole(Data.Entity.Twipler.VisitorRole.ThemeModerator);

                case Condition.SettingValueValidator:
                    return Data.Entity.Twipler.Validator.IsValid(((Twipler.Setting)obj).ValueType, ((Twipler.Setting)obj).SettingValue);
                default:
                    return false;
            }
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditIf : System.Attribute
    {
        private string _methodName;

        public EditIf(string methodName)
        {
            _methodName = methodName;
        }

        public bool CanEdit(Data.Entity.Base obj, System.Reflection.PropertyInfo pi)
        {
            MethodInfo mi = obj.GetType().GetMethod(_methodName, BindingFlags.Public | BindingFlags.Instance);
            if (mi == null)
                return false;

            return (bool)mi.Invoke(obj, null);
        }
    }

    [System.AttributeUsage(System.AttributeTargets.Property)]
    public class EditStringType : System.Attribute
    {
        public enum Types
        {
            Normal,
            Required,
            LargeText,
            ValueType
        };

        private Types _type;
        public Types StringType { get { return _type; } }

        public EditStringType(Types type)
        {
            _type = type;
        }

        public bool IsValid(Data.Entity.Base entity, System.Reflection.PropertyInfo pi, string val)
        {
            switch (_type)
            {
                case Types.ValueType:
                    // Get the entities ValueType Property
                    System.Reflection.PropertyInfo valPi = entity.GetType().GetProperty("ValueType");
                    if (valPi == null)
                        return false;

                    // Is it's value a Data.Entity.Twipler.ValueType
                    object obj = valPi.GetValue(entity, null);
                    if (typeof(Data.Entity.Twipler.ValueType).IsAssignableFrom(obj.GetType()) == false)
                        return false;

                    // Validate the string based on the type
                    Data.Entity.Twipler.ValueType valType = (Data.Entity.Twipler.ValueType)obj;
                    switch (valType)
                    {
                        case Data.Entity.Twipler.ValueType.Integer:
                            int i;
                            return int.TryParse(val, out i);

                        default:
                            return true;
                    }

                case Types.Required:
                    return !string.IsNullOrEmpty(val);

                default:
                    return true;
            }            
        }
    }

}